import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common';
import { validate, ValidationError } from 'class-validator';
import { plainToClass } from 'class-transformer';

interface ObjType {
  isString?: string;
  maxLength?: string;
  minLength?: string;
  isNumber?: string;
  Contains?: string;
  Min?: string;
  Max?: string;
  IsEmail?: string;
  Length?: string;
  IsNotEmpty?: string;
  IsBoolean?: string;
  IsMobilePhone?: string;
  IsDefined?: string;
  NotAllowDuplicate?: string;
}

const getErrorValues = (obj: ObjType): string => {
  const keys: string[] = Object.keys(obj)
  const res = []
  for(let key of keys) {
    res.push(obj[key])
  }
  return res.join()
}

@Injectable()
export class ValidationPipe implements PipeTransform {
  async transform(value: any, metadata: ArgumentMetadata) {
    const { metatype } = metadata
    if(!metatype || !this.toValidate(metatype)) {
      return value
    }
    console.log(metatype)
    const object = plainToClass(metatype, value);
    console.log(value)
    console.log(object, 111)
    const errors = await validate(object, { whitelist: true, skipMissingProperties: true, validationError: { target: false }, forbidNonWhitelisted: true })
    const message: any[] = []
    if(errors.length > 0) {
      // console.log(errors[0].constraints)
      errors.forEach(item => {
        message.push(getErrorValues(item.constraints))
      })
      // throw new BadRequestException(message[0]);
      throw new BadRequestException(message)
    }
    return value;
  }

  private toValidate(metatype) {
    const types = [String, Boolean, Number, Array, Object];
    return !types.find(type => metatype === type)
  }
}